﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Org.BouncyCastle.Utilities.Encoders;
using System.Configuration;
using Newtonsoft.Json;
using System.Net;
using System.IO;
using System.Collections.Specialized;
using UFC.Common;
using System.Collections;
using System.Data;
using UFC.DBUtility;
using System.Xml;
using SyslogNet.Client;
using SyslogNet.Client.Serialization;
using SyslogNet.Client.Transport;

namespace SendIndustrialNetwork
{
    public class SendIndustrialNetworkData
    {
        private static string appAuthUrl = ConfigurationManager.AppSettings["appAuthUrl"];//认证接口
        private static string password = ConfigurationManager.AppSettings["password"];//应用密码
        private static string appId = ConfigurationManager.AppSettings["appId"];//应用ID
        private static string strPassword = SM3Util.ToSM3HexStr(password);//SM3国密加密方式
        private static string fileUploadUrl = ConfigurationManager.AppSettings["fileUploadUrl"];//文件上传接口
        private static Dictionary<string, string> dic = new Dictionary<string, string>();
        static SendIndustrialNetworkData(){
            dic.Add("appId", appId);
            dic.Add("password", strPassword);
        }

        public void SendIndustrialNetworkDataSync()
        {
            DataTable szbDt = getSZB_Data();
            foreach (DataRow row in szbDt.Rows)
            {
                var xml = CreateXML(row);
                FileUpload("11012", row, xml);//三坐标
            }
            DataTable rbDt = getRB_Data();
            foreach (DataRow row in rbDt.Rows)
            {
                var xml = CreateXML(row);
                FileUpload("11013", row, xml);//热表
            }
        }
        /// <summary>
        /// 获取token
        /// </summary>
        public string GetAppAuthToken(string port)
        {
            var token = CacheHelper.GetToken("token_" + port);
            if (string.IsNullOrWhiteSpace(token))
            {
                string appauthUrl = string.Format(appAuthUrl, port);
                string rspStr = HttpWebRequestHelper.HttpPostSync(appauthUrl, JsonConvert.SerializeObject(dic), "application/json", "", new Dictionary<string, string>());
                LogHelp.WriteLog("GetAppAuthToken" + (port == "11012" ? "三坐标：" : "热表：") + rspStr);
                if (!string.IsNullOrWhiteSpace(rspStr))
                {
                    var jsonObj = JsonConvert.DeserializeObject<Rspresult>(rspStr);
                    if (jsonObj.code == "200")
                    {
                        CacheHelper.SetToken("token_" + port, jsonObj.token);
                        token = jsonObj.token;
                    }
                }
            }
            return token;
        }
        /// <summary>
        /// 文件上传
        /// </summary>
        public void FileUpload(string port, DataRow row, string xml)
        {
            var Token=GetAppAuthToken(port);
            if(!string.IsNullOrWhiteSpace(Token)){
                Dictionary<string, string> dic = new Dictionary<string, string>();
                dic.Add("Token", Token);//认证接口返回的token凭证--
                dic.Add("FileName", System.Web.HttpUtility.UrlEncode("123.xml"));//文件名，包含文件的路径
                dic.Add("WenjianqIcaoren", System.Web.HttpUtility.UrlEncode("刘美美"));//文件起草人
                dic.Add("Shenpiren", System.Web.HttpUtility.UrlEncode("刘美美"));//审批人
                dic.Add("Miji", "4");//密级
                dic.Add("Baomiqixian", "10,0,0");//保密期限
                dic.Add("Qianfaren", System.Web.HttpUtility.UrlEncode("刘美美"));//签发人
                dic.Add("Wenjiansanliezhi", "7");//文件散列值--
                dic.Add("Beizhu", System.Web.HttpUtility.UrlEncode("备注"));//备注
                var FileUploadUrl = string.Format(fileUploadUrl,port);
                string rspStr = HttpWebRequestHelper.HttpPostSync(FileUploadUrl, xml, "", "", dic);//@"{'msg':'文件上传成功','code':'200'}"; //
                LogHelp.WriteLog("FileUpload"+(port == "11012" ? "三坐标：" : "热表：")+rspStr);
                if (!string.IsNullOrWhiteSpace(rspStr))
                {
                    var jsonObj = JsonConvert.DeserializeObject<Rspresult>(rspStr);
                    Update_Sendgkwdata(row["ID"].ToString());//更新Sendgkwdata--字段--issend=1 防止多次发送

                    Dictionary<string, string> LogDic = new Dictionary<string, string>();
                    LogDic.Add("operateUser", row["create_name"].ToString());//操作人
                    LogDic.Add("sourceip", "20.10.22.33");//源地址
                    LogDic.Add("destip", "20.12.18.11");//目的地址
                    LogDic.Add("fileType", "xml");//文件类型
                    LogDic.Add("fileNo", "");//文件序号
                    LogDic.Add("fileName", "123.xml");//文件名称
                    LogDic.Add("fileSize", Encoding.UTF8.GetBytes(xml).Length.ToString());//文件大小
                    LogDic.Add("result", jsonObj.code == "200" ? "上传成功" : "上传失败");//结果
                    LogDic.Add("desc", "上传订单" + row["mfgordername"].ToString() + " 批次" + row["containername"].ToString() + "的xml文件至" + (port == "11012" ? "三坐标" : "热表") + "系统");//文件描述
                    LogDic.Add("date", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:sss"));//时间
                    SendSysLogByUDP(JsonConvert.SerializeObject(LogDic), ConfigurationManager.AppSettings["SM_SysLog_HostName"], Convert.ToInt32(ConfigurationManager.AppSettings["SM_SysLog_Port"]));//上传日志至涉密网日志系统
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public class Rspresult {
            public string code { set; get; }
            public string token { set; get; }
            public string msg { set; get; }
        }

        /// <summary>
        /// 获取检测数据---推送三坐标
        /// </summary>
        /// <returns></returns>
        public DataTable getSZB_Data()
        {
            try
            {
                var strSql = @" select sd.ID,cf.mfgordername,cf.containername,cf.dispatchnum,cf.containertype,cf.productname,cf.planqty,cf.productdescription,
                         sc.createdate,sc.workcheckpointresultnote,sc.workcheckpointresultnotedis,
                         e.fullname create_name,e.employeename,f.factoryname,ws.workflowstepname,sp.checkpointnote,sp.checkpointnotedis,
                         sp.name,sp.keycheck,sp.meopcheck,sp.checktype
                         from Sendgkwdata sd 
                         left join STEPCHECKPOINTRESULT sc on sc.stepcheckpointresultid=sd.parentid
                         left join containercurrentinfo cf on cf.containerid=sc.containerid
                         left join stepcheckpoint sp on sp.stepcheckpointid=sc.stepcheckpointid
                         left join factory f on f.factoryid=sc.factoryid
                         left join employee e on e.employeeid=sc.workerid
                         left join workflowstep ws on ws.workflowstepid=sp.workflowstepid
                         where sd.sendtype='2' AND nvl(sd.issend,0)<>'1'";
                DataTable myDS = OracleHelper.QueryTable(strSql, null);
                return myDS;
            }
            catch (Exception e)
            {
                return null;
            }
        }
        /// <summary>
        /// 获取派工数据---推送热表
        /// </summary>
        /// <returns></returns>
        public DataTable getRB_Data()
        {
            try
            {
                var strSql = @" select sd.ID,cf.mfgordername,cf.containername,cf.dispatchnum,cf.containertype,cf.productname,cf.planqty,cf.productdescription,
                         csd.createdate,csd.qty,f.factoryname,e.fullname create_name,e.employeename create_employeename,
                         nvl(e1.fullname,csp.fullname) worker_fullname,nvl(e1.employeename,csp.employeename) worker_mployeename,
                         ws.workflowstepname,rs.resourcename,rs.description,t.teamname,wce.workcentername
                         from Sendgkwdata sd
                         LEFT JOIN CONTAINERSTEPDISPATCH csd on csd.containerstepdispatchid=sd.parentid
                         left JOIN (SELECT listagg(ee.fullname,',') within group( order BY cd.containerstepdispatchid) fullname,
                         listagg(ee.employeename,',') within group( order BY cd.containerstepdispatchid) employeename,
                         cd.containerstepdispatchid FROM containerstepdispatchdetail cd 
                         LEFT JOIN employee ee ON ee.employeeid=cd.workerid GROUP BY cd.containerstepdispatchid) csp on csp.containerstepdispatchid=csd.containerstepdispatchid--派工多人
                         left join containercurrentinfo cf on cf.containerid=csd.containerid
                         left join factory f on f.factoryid=csd.factoryid
                         left join employee e on e.employeeid=csd.employeeid
                         left join employee e1 on e1.employeeid=csd.workerid
                         left join workflowstep ws on ws.workflowstepid=csd.workflowstepid
                         left join resourcedef rs on rs.resourceid=csd.resourceid
                         left join team t on t.teamid=csd.teamid
                         left join workcenter wce on wce.workcenterid=csd.workcenterid
                         where sd.sendtype='1' AND nvl(sd.issend,0)<>'1'";
                DataTable myDS = OracleHelper.QueryTable(strSql, null);
                return myDS;
            }
            catch (Exception e)
            {
                return null;
            }
        }
        /// <summary>
        /// 发送成功，更新为1
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Update_Sendgkwdata(string id)
        {
            bool result = false;
            try
            {
                var updateStr = @"  update Sendgkwdata set issend=1 where ID='" + id + "' ";
                result = OracleHelper.ExecuteSql(updateStr) > 0;
            }
            catch (Exception ex)
            {
                result = false;
            }
            return result;
        }
        /// <summary>
        /// 生成xml
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public string CreateXML(DataRow row)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", ""));
                XmlNode ReqNode = doc.CreateElement("ReqMsg");
                XmlNode headerNode = doc.CreateElement("header");
                XmlNode senderNode = doc.CreateElement("sendSysName");
                senderNode.InnerText = "APP_MES";
                XmlNode rcvNode = doc.CreateElement("rcvSysName");
                rcvNode.InnerText = "APP_ERP";
                XmlNode extConfigNode = doc.CreateElement("extConfig");
                XmlNode isReTryNode = doc.CreateElement("isReTry");
                isReTryNode.InnerText = "false";

                extConfigNode.AppendChild(isReTryNode);
                headerNode.AppendChild(senderNode);
                headerNode.AppendChild(rcvNode);
                headerNode.AppendChild(extConfigNode);
                ReqNode.AppendChild(headerNode);
                XmlNode documentNode = doc.CreateElement("document");
                string strData = "";
                foreach (var _key in row.Table.Columns)
                {
                    if (_key != "ID")
                    {
                        strData = string.Format("{0}<{1}>{2}</{1}>", strData, _key, row[_key.ToString()].ToString());
                    }
                }
                documentNode.AppendChild(doc.CreateCDataSection("<root>" + strData + "</root>"));
                ReqNode.AppendChild(documentNode);
                doc.AppendChild(ReqNode);
                return doc.InnerXml;
            }
            catch (Exception e)
            {
                LogHelp.WriteError("工控网XML", e);
                return string.Empty;
            }
        }

        /// <summary>
        /// 使用UDP方式、发送日志给日志系统
        /// </summary>
        /// <param name="message">日志消息内容</param>
        /// <param name="hostname">日志系统IP地址</param>
        /// <param name="port">端口</param>
        public void SendSysLogByUDP(string message, string hostname, int port)
        {
            SyslogMessage msg = new SyslogMessage(
                DateTimeOffset.Now,
                Facility.LogAlert, // Facility - LogAlert
                Severity.Critical, // Severity - Critical
                Environment.MachineName, // MachineName
                "MES", // AppName
                 null, // ProcId
                "Mes_MsgType", // Message type name
                message); // message to be sent---
            ISyslogMessageSerializer serializer = (ISyslogMessageSerializer)new SyslogRfc3164MessageSerializer();//SyslogRfc5424MessageSerializer--SyslogRfc3164MessageSerializer
            ISyslogMessageSender sender = (ISyslogMessageSender)new SyslogUdpSender(hostname, port);//SyslogUdpSender--SyslogTcpSender
            sender.Send(msg, serializer);

            LogHelp.WriteLog("发送给syslog:" + JsonConvert.SerializeObject(msg));
        }

        #region 三坐标数据

        //DataTable PartInfo = getPartInfo();
        //   foreach (DataRow row in PartInfo.Rows) {
        //       DataTable TaskInfo = getTaskInfo();
        //       DataTable DimensionList=getDimensionList();
        //       var xml = CreateXml(row, TaskInfo.Rows[0],DimensionList);
        //   }
        /// <summary>
        /// PartInfo数据
        /// </summary>
        /// <returns></returns>
        private DataTable getPartInfo()
        {
            try
            {
                var strSql = @"select 'xxx'part_code,'xxx'part_name,'S'PartStage,'8.0'PartVer,'123456'PartDrawingCode,''IsTemp,'50'OPLabel,'数控车'OPName,'B.01'OPVersion,'机匣'WorkShop,'机加'ProcessType,'Y'IsKeyOP from dual";
                DataTable myDS = OracleHelper.QueryTable(strSql, null);
                return myDS;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        /// <summary>
        /// TaskInfo数据
        /// </summary>
        /// <returns></returns>
        private DataTable getTaskInfo()
        {
            try
            {
                var strSql = @"select '2001_1A'batch_code,'2001_1A'l_batch_code,'100' batch_no,'1-10,12,14-102'sn,'9'First_sn,'9'InspectID,'2023-01-12 12:32:23'CreationTime,''operator from dual";
                DataTable myDS = OracleHelper.QueryTable(strSql, null);
                return myDS;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        /// <summary>
        /// DimensionList数据
        /// </summary>
        /// <returns></returns>
        private DataTable getDimensionList()
        {
            try
            {
                var strSql = @"select '49'dimension_no,'Z101'dimension_flag,'0'nominal,'0.0215'upper_tol,'0'lower_tol,'CMM'measured_tools,'0.00127'measured_value,'2023-01-11 12:12:12'measured_time from dual
                               union all select '50'dimension_no,'Z102'dimension_flag,'0'nominal,'0.0216'upper_tol,'0'lower_tol,'CMM'measured_tools,'0.00128'measured_value,'2023-01-11 12:12:12'measured_time from dual";
                DataTable myDS = OracleHelper.QueryTable(strSql, null);
                return myDS;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        /// <summary>
        /// 组装xml
        /// </summary>
        /// <param name="prow"></param>
        /// <param name="trow"></param>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string CreateXml(DataRow prow, DataRow trow, DataTable dt)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", ""));
                XmlNode documentNode = doc.CreateElement("InspectValues");
                #region 组装PartInfo xml
                XmlNode PartInfoNode = doc.CreateElement("PartInfo");
                foreach (var _key in prow.Table.Columns)
                {
                    XmlNode node = doc.CreateElement(_key.ToString());
                    node.InnerText = prow[_key.ToString()].ToString();
                    PartInfoNode.AppendChild(node);
                }
                documentNode.AppendChild(PartInfoNode);
                #endregion

                #region 组装TaskInfo xml
                XmlNode TaskInfoNode = doc.CreateElement("TaskInfo");
                foreach (var _key in trow.Table.Columns)
                {
                    XmlNode node = doc.CreateElement(_key.ToString());
                    node.InnerText = trow[_key.ToString()].ToString();
                    TaskInfoNode.AppendChild(node);
                }
                documentNode.AppendChild(TaskInfoNode);
                #endregion

                #region 组装DimensionList xml
                XmlNode DimensionListNode = doc.CreateElement("DimensionList");
                foreach (DataRow row in dt.Rows)
                {
                    XmlNode Dimensions = doc.CreateElement("Dimensions");
                    foreach (var _key in row.Table.Columns)
                    {
                        XmlNode node = doc.CreateElement(_key.ToString());
                        node.InnerText = row[_key.ToString()].ToString();
                        Dimensions.AppendChild(node);
                    }
                    DimensionListNode.AppendChild(Dimensions);
                }
                documentNode.AppendChild(DimensionListNode);
                #endregion

                doc.AppendChild(documentNode);
                return doc.InnerXml;
            }
            catch (Exception e)
            {
                LogHelp.WriteError("MES发送三坐标数据XML", e);
                return string.Empty;
            }
        }

        #endregion 

    }
}
